﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cpp_class_lib;

namespace USMCdotNET
{
    //rectangle class
    public sealed class BaseRectangle:IPathElement
    {
        Vector<int> destination;
        public StartPRMSLine[] StPrms;
        Devices dev;
        Vector<float> speed;
        public Vector<int> Destination { get { return destination; } set { destination = value; } }
        bool atProcess = false;
        bool finished = false;
        float velocity;
        bool my_dir;
        int my_shift;
        int my_x;
        int my_y;
        Checker m_checker;
        public bool AtProcess
        {
            get { return atProcess; }
        }
        public bool Accomplished
        {
            get { return finished; }
        }
        public float Velocity
        {
            get { return velocity; }
            set
            {
                velocity = value;
                speed = new Vector<float>(destination.X, destination.Y, (a, b) => (a + b), (a, b) => (a * b), (a) => ((float)Math.Sqrt(a)));
                speed *= (velocity / speed.Length);
            }
        }
        public StartPRMSLine FirstStPrms
        {
            get { return StPrms[0]; }
        }
        public StartPRMSLine SecondStPrms
        {
            get { return StPrms[1]; }
        }
        public BaseRectangle(int x, int y, int shift, float sp, StartPRMSLine[] a, Devices d, bool dir, Checker checker)
        {
            //BaseLine buf;
            //int num;
            dev = d;
            StPrms = a;
            velocity = sp;
            my_dir = dir;
            my_shift = shift;
            my_x = x;
            my_y = y;
            m_checker = checker;
           /* if (dir) //x shift case
            {
                num = x / shift;
                for (int i = 0; i < num; i++) //тестировать! сделть по аалогии с линиями
                {
                    buf = new baseline(shift * i, y, sp, stprms, d); //direct y lines тут отклоение !!!!
                    
                    path.add(buf);
                    buf = new baseline(shift * (i + 1), y, sp, stprms, d); // shift x 1 side lines
                    
                    path.add(buf);
                    buf = new baseline(shift * (i + 1), 0, sp, stprms, d); //backward y lines
                    
                    path.add(buf);
                    buf = new baseline(shift * (i + 2), 0, sp, stprms, d); //shift x 2 side lines
                    
                    path.add(buf);
                }

            }
            else //y  shift case
            {
                num = y / shift;
                for (int i = 0; i < num; i++)
                {
                    buf = new baseline(x, 0 + shift * i, sp, stprms, d); //direct x lines
                    path.add(buf);
                    buf = new baseline(x, shift, sp, stprms, d); // shft y lines
                    path.add(buf);
                    buf = new baseline(0, shift * i, sp, stprms, d); //backward x lines
                    path.add(buf);
                    buf = new baseline(shift * (i + 1), 0, sp, stprms, d); //shift y 2 side lines
                    path.add(buf);
                }
            }*/


        }

        public void Move()
        {
            //TODO:проверить
            finished = false;
            atProcess = true;
            dev.GetSTATE();
            int start_x = dev.STATE[0].CurPos;
            int start_y = dev.STATE[1].CurPos;
            BaseLine currentLine;
            if (my_dir)
            {
                if (m_checker.IsCancelled == true)
                    return;
                currentLine = new BaseLine(start_x, my_y, velocity, StPrms, dev);
                currentLine.Move();
                int current_x=start_x;
                int shift;
                Func<bool> continueMoving;
                if (start_x < my_x)
                {
                    shift = my_shift;
                    continueMoving = () => (current_x + shift <= my_x);
                }
                else
                {
                    shift = -my_shift;
                    continueMoving = () => (current_x+shift >= my_x);
                }
                bool b = false;
                while (continueMoving())
                {
                    if (!b)
                    {
                        if (m_checker.IsCancelled == true)
                            return;
                        current_x += shift;
                        currentLine = new BaseLine(current_x, my_y, velocity, StPrms, dev);
                        currentLine.Move();
                        b = true;
                    }
                    else
                    {
                        if (m_checker.IsCancelled == true)
                            return;
                        currentLine = new BaseLine(current_x, start_y, velocity, StPrms, dev);
                        currentLine.Move();
                        current_x += shift;
                        if (m_checker.IsCancelled == true)
                            return;
                        currentLine = new BaseLine(current_x, start_y, velocity, StPrms, dev);
                        currentLine.Move();
                        if (m_checker.IsCancelled == true)
                            return;
                        currentLine = new BaseLine(current_x, my_y, velocity, StPrms, dev);
                        currentLine.Move();
                        b = false;
                    }
                }
            }
            else
            {
                int current_y = start_y;
                if (m_checker.IsCancelled == true)
                    return;
                currentLine = new BaseLine(my_x, start_y, velocity, StPrms, dev);
                currentLine.Move();
                int shift;
                Func<bool> continueMoving;
                if (start_y < my_y)
                {
                    shift = my_shift;
                    continueMoving = () => (current_y+shift <= my_y);
                }
                else
                {
                    shift = -my_shift;
                    continueMoving = () => (current_y + shift >= my_y);
                }
                bool b = false;
                while (continueMoving())
                {
                    if (!b)
                    {
                        current_y += shift;
                        if (m_checker.IsCancelled == true)
                            return;
                        currentLine = new BaseLine(my_x, current_y, velocity, StPrms, dev);
                        currentLine.Move();
                        b = true;
                    }
                    else
                    {

                        if (m_checker.IsCancelled == true)
                            return;
                        currentLine = new BaseLine(start_x, current_y, velocity, StPrms, dev);
                        currentLine.Move();
                        current_y += shift;
                        if (m_checker.IsCancelled == true)
                            return;
                        currentLine = new BaseLine(start_x, current_y, velocity, StPrms, dev);
                        currentLine.Move();
                        if (m_checker.IsCancelled == true)
                            return;
                        currentLine = new BaseLine(my_x, current_y, velocity, StPrms, dev);
                        currentLine.Move();
                        b = false;
                    }
                }
            }
            if (m_checker.IsCancelled == true)
                return;
            currentLine = new BaseLine(my_x, my_y, velocity, StPrms, dev);
            currentLine.Move();
            finished = true;
            atProcess = false;
        }
    }
}
